//
// Created by QU on 2024/1/21.
//

#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <map>
#include <set>

// boost library
#include <boost/noncopyable.hpp>

// using namespace
using std::cin, std::cout, std::endl;
using std::string;

using boost::noncopyable;

// noncopyable允许程序轻松地实现一个禁止拷贝的类.    位于boost::noncopyable;
// 需要包含<boost/noncopyable.hpp>      真正的实现在 <boost/core/noncopyable.hpp>

// 在c++中定义一个类的时候如果没有明确定义拷贝构造函数和拷贝赋值操作函数, 编译器将会为你自动的生成这两个函数.
// 一般的类似下面的这样的

/*
class empty_class {
public:
    empty_class(const empty_class &) {}
    empty_class &operator=(const empty_class &) {}
};
*/

// 这样的有好处, 可以自动的支持swap(), 符合容器的拷贝语义, 拷贝复制操作符等等.

// 但是有些时候我们不需要这样的类
// 这是一个很经典的c++惯用方法, 就是将上面的两个函数声明为私有.

/*
class do_not_copy {
private:
    do_not_copy(const do_not_copy &);
    void operator=(do_not_copy &);      // 仅仅声明就可以, 不需要实现代码.
};
*/

// 如果需要很多这样的类, 重复这样的代码是相当乏味的, 因此, boost给我们提供了这样的一个类 boost.noncopyable.
// 上面的例子可以简化为:

class do_not_copy : boost::noncopyable {        // 注意这里, 使用默认的私有继承是允许的. C++类为什么默认私有继承.
    //    ......
};

int main(int argc, char const *argv[]){
    // 如果定义了这样的类, 使用下面的代码将会报错
/*
    do_not_copy d1;
    do_not_copy d2(d1);
    do_not_copy d3;
    d3 = d1;
    // error: use of deleted function 'do_not_copy::do_not_copy(const do_not_copy&)'
*/

// 实现

/*
class noncopyable
{
protected:
    // default默认构造函数的作用
    // 在C++中约定如果一个类中自定义了带参数的构造函数，那么编译器就不会再自动生成默认构造函数，也就是说该类将不能默认创建对象，只能携带参数进行创建一个对象；
    // 但有时候需要创建一个默认的对象但是类中编译器又没有自动生成一个默认构造函数，那么为了让编译器生成这个默认构造函数就需要default这个属性。
        BOOST_CONSTEXPR noncopyable() = default;        // 默认的构造和析构函数是受保护的
        ~noncopyable() = default;

    // private: // 我这个版本是没有的, 取而代之的是=delete的写法, 我也是第一次见.
        noncopyable( const noncopyable& ) = delete;
        noncopyable& operator=( const noncopyable& ) = delete;
    // 当我们定义一个类的成员函数时，如果后面使用"=delete"去修饰，那么就表示这个函数被定义为deleted，也就意味着这个成员函数不能再被调用
};
*/

}
